Skip to content

Fix multi-release JAR detection on Windows and add integration test - #563

Merged
gnodet merged 1 commit into
apache:masterfrom
elharo:fix-557
Sep 24, 2026
Merged

gnodet merged 1 commit into
apache:masterfrom
elharo:fix-557

Conversation

@elharo

@elharo elharo commented Jul 19, 2026 •

Copy link
Copy Markdown
Contributor

Adds an integration test that verifies the Multi-Release: true manifest entry is added when the class output contains META-INF/versions/ files.

The detection logic in AbstractJarMojo uses File.separatorChar to build the path prefix, which matches the platform separator used by DirectoryScanner. This test passes on all platforms (Linux, macOS, Windows).

@elharo elharo added the bug Something isn't working label Jul 19, 2026
@elharo
elharo force-pushed the fix-557 branch 2 times, most recently from 9f77b32 to 98441ac Compare July 19, 2026 23:29
@elharo
elharo marked this pull request as draft July 20, 2026 10:14
@elharo elharo changed the title Multi-release JAR detection broken on Windows (File.separatorChar mismatch) Add integration test for multi-release JAR detection Jul 20, 2026
@elharo
elharo marked this pull request as ready for review July 20, 2026 10:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Adds a Maven Invoker integration test to validate that the built JAR is marked as multi-release (Multi-Release: true) when META-INF/versions/ content is present, improving cross-platform confidence (including Windows).

Changes:

  • Added a new Maven Invoker IT project (MJAR-557-detect-mjar) that packages META-INF/versions/9/... content.
  • Added a verify.groovy script to assert Multi-Release manifest attribute is set to true.
  • Updated root pom.xml excludes to avoid RAT/header checks on the added plain text fixture.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/it/MJAR-557-detect-mjar/verify.groovy Verifies the built JAR manifest contains Multi-Release: true.
src/it/MJAR-557-detect-mjar/src/main/resources/META-INF/versions/9/test.txt Adds a META-INF/versions/9/ fixture to trigger MRJAR detection.
src/it/MJAR-557-detect-mjar/pom.xml Defines the IT Maven project that builds a JAR using the plugin under test.
src/it/MJAR-557-detect-mjar/invoker.properties Configures Invoker execution constraints and test description.
pom.xml Excludes the fixture text file from checks (e.g., RAT/license header validation).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/it/MJAR-557-detect-mjar/verify.groovy Outdated
Comment thread src/it/MJAR-557-detect-mjar/verify.groovy Outdated
@elharo

elharo commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

Addressed Copilot review comments:

  1. Resource leak: Wrapped JarFile in withCloseable to ensure the handle is released.
  2. Assertion message: Added a diagnostic message to the assertion showing the actual Multi-Release value on failure.
  3. PR description: Removed the module-info.class example since the test uses a text file (any entry under META-INF/versions/ triggers detection).

@elharo
elharo requested a review from slachiewicz August 26, 2026 10:46

@slachiewicz slachiewicz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General looks good.
There are unresolved copilot issues.

@gnodet gnodet changed the title Add integration test for multi-release JAR detection Fix multi-release JAR detection on Windows and add integration test Sep 24, 2026
@gnodet

gnodet commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Added the actual code fix in the latest commit: replaced File.separatorChar with a literal '/' in AbstractJarMojo. FileSetManager.getIncludedFiles() always returns forward-slash-separated paths regardless of the OS, so the prefix check must use / — JAR paths are also always forward-slash per the specification. The java.io.File import is no longer needed after the fix and has been removed.

The IT (with test.txt under META-INF/versions/9/) is correct as-is: any file under META-INF/versions/ triggers the detection, not just module-info.class. The fixture exercises the actual code path.

The withCloseable and assertion message from the second commit are already in place.

@gnodet-bot gnodet-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bug fix is correct, but there is a critical integration problem that will need to be resolved before this can merge.

Conflict with bcae92d (#508)

The createArchive() method that this PR patches no longer exists on master. Commit bcae92d (Migrate from Maven Archiver to standard jar tool, PR #508) replaced the entire FileSetManager-based code path with a FileCollector approach:

// master — createArchives() uses FileCollector, no FileSetManager at all
var files = new FileCollector(this, executor, classesDirectory, matcherFactory);
Files.walkFileTree(classesDirectory, files);

FileCollector uses Path.endsWith(VERSIONS) to detect META-INF/versions/ directories (line 289 of FileCollector.java):

if (detectMultiReleaseJar && directory.endsWith(VERSIONS)) {

Path.endsWith(String) compares path components, not raw strings, so it is already OS-independent — the Windows File.separatorChar bug this PR fixes does not exist on master. GitHub confirms this: mergeableState: dirty.

Action required: rebase this branch on master. After the rebase, the AbstractJarMojo.java change will conflict and should be dropped — the fix is already in place via FileCollector. The IT (MJAR-557-detect-mjar) is still valuable and should be kept as-is; it exercises the real code path and adds cross-platform confidence.

Prior review comments

The Copilot findings (JarFile not closed, missing assertion message) have both been addressed — withCloseable is in place and the assertion includes a diagnostic message. slachiewicz's CHANGES_REQUESTED can be re-evaluated after the rebase once the conflict is resolved.

This review was generated by an AI agent, Hermès on behalf of @gnodet.

@gnodet-bot gnodet-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review after the latest two commits (d6b5c31, 3634093).

Prior findings — all resolved

Previous bot review (COMMENT on d6b5c31503ed): flagged a merge conflict: the createArchive() / FileSetManager code path no longer exists on master after PR #508 replaced it with a FileCollector / jar-tool architecture.

Resolved by 3634093: the merge conflict was properly resolved by taking master's AbstractJarMojo (with the new FileCollector architecture) and dropping the File.separatorChar fix — which is moot since FileCollector.preVisitDirectory() uses Path.endsWith(VERSIONS) (path-component comparison, already OS-agnostic).

slachiewicz's CHANGES_REQUESTED: the two flagged items (JarFile not closed; assertion without message) were addressed in a52ae29. The test.txt fixture comment was answered by elharo — any entry under META-INF/versions/ triggers detection, not just .class files. The concerns are resolved.

Current diff review

The current diff is integration-test only. No production code is modified.

  • verify.groovy: withCloseable handles the JarFile resource leak; assertion includes a diagnostic message. Correct.
  • invoker.java.version = 9+: appropriate guard for multi-release JAR support.
  • IT fixture: HelloWorld.java provides a base class, ensuring META-INF/versions/9/ stays as a versioned layer under --release 9 and is not promoted to base by Archive.prune(). The jar tool then sets Multi-Release: true automatically. Logic is sound.
  • pom.xml checkstyle exclusion: path matches exactly; needed because test.txt has no license header and should not be checked.

No issues found. CI is pending (not failing).

This review was generated by an AI agent, Hermès on behalf of @gnodet.

@gnodet
gnodet requested a review from slachiewicz September 24, 2026 13:17
@gnodet gnodet added the java Pull requests that update Java code label Sep 24, 2026
- Fix multi-release JAR detection on Windows: FileSetManager.getIncludedFiles()
  returns forward-slash paths regardless of OS; replace File.separatorChar with
  literal '/' to match the JAR spec and FileSetManager normalization
- Add MJAR-557 integration test that verifies Multi-Release: true is set in the
  manifest when META-INF/versions/ files are present
- Update IT for new FileCollector architecture: FileCollector uses Path
  comparisons, so the Windows bug is already fixed on master; add HelloWorld.java
  base class so the versioned entry is correctly handled with --release 9

Fixes: MJAR-557
@gnodet
gnodet merged commit 22888ad into apache:master Sep 24, 2026
1 check passed
@github-actions github-actions Bot added this to the 4.0.0-beta-2 milestone Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working java Pull requests that update Java code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants